package com.googlecode.monitoring.db.builders;

import com.googlecode.monitoring.builders.ItemToCheckBuilder;
import com.googlecode.monitoring.builders.PersonBuilder;
import com.googlecode.monitoring.dao.XmlUtils;
import com.googlecode.monitoring.db.model.DataSourceItem;
import com.googlecode.monitoring.db.model.DbItemToCheck;
import com.googlecode.monitoring.db.model.MaxAgeOfData;
import com.googlecode.monitoring.db.model.TableOfData;
import com.googlecode.monitoring.exception.DataDaoException;
import com.googlecode.monitoring.model.ItemToCheck;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import java.util.List;
import java.util.Map;

/**
 * Author: Sergiy Doroshenko
 * Date: Sep 20, 2010
 * Time: 3:29:57 PM
 */
public class DbItemToCheckBuilder implements ItemToCheckBuilder{
    private PersonBuilder personBuilder;
   

    @Override
    public ItemToCheck build(Element xmlItemElmnt) {
       String name = xmlItemElmnt.getAttribute("name");
        if (name.isEmpty())
            throw new DataDaoException("item with empty name");
        String id = xmlItemElmnt.getAttribute("id");
        if (id.isEmpty())
            throw new DataDaoException("item with empty id");
        DbItemToCheck dbItem = new DbItemToCheck();
        dbItem.setName(name);
        dbItem.setId(id);
        Node databaseItemNode = xmlItemElmnt.getElementsByTagName("datasource").item(0);
        Node tableNode = xmlItemElmnt.getElementsByTagName("table").item(0);
        Node maxAgeOfDataNode = xmlItemElmnt.getElementsByTagName("maxAgeOfData").item(0);
        Node timeEventNode = xmlItemElmnt.getElementsByTagName("eventTime").item(0);
        NodeList personNode = xmlItemElmnt.getElementsByTagName("person");
        Node descriptionNode = xmlItemElmnt.getElementsByTagName("description").item(0);

        DataSourceItem dataSourceItemTemp = buildDataSourceItemFromNode(databaseItemNode);
        if(dataSourceItems != null){
            dbItem.setDataSourceItem(dataSourceItems.get(dataSourceItemTemp.getId()));
        }else{
            dbItem.setDataSourceItem(dataSourceItemTemp);
        }

        dbItem.setTable(buildTableFromNode(tableNode));
        dbItem.setMaxAgeOfData(buildmaxAgeOfData(maxAgeOfDataNode));
        dbItem.setEventTime(xmlUtils.buildEventTime(timeEventNode));
        dbItem.setResponsiblePersons(personBuilder.buildPersons(personNode));
        dbItem.setDescr(buildDescription(descriptionNode));
        return dbItem;
    }

        public DataSourceItem buildDataSourceItemFromNode(Node datasourceNode) {
        DataSourceItem dataSourceItem = new DataSourceItem();
        if (datasourceNode.getAttributes().getNamedItem("id") != null) {
            dataSourceItem.setId(datasourceNode.getAttributes().getNamedItem("id").getNodeValue());
        }
        if (datasourceNode.getAttributes().getNamedItem("name") != null) {
            dataSourceItem.setName(datasourceNode.getAttributes().getNamedItem("name").getNodeValue());
        }
        if (datasourceNode.getAttributes().getNamedItem("beanName") != null) {
            dataSourceItem.setBeanName(datasourceNode.getAttributes().getNamedItem("beanName").getNodeValue());
        }
        if (datasourceNode.getAttributes().getNamedItem("descr") != null) {
            dataSourceItem.setDescr(datasourceNode.getAttributes().getNamedItem("descr").getNodeValue());
        }

        return dataSourceItem;
    }

    private TableOfData buildTableFromNode(Node tableNode) {
        TableOfData tableOfData = new TableOfData();
        if (tableNode.getAttributes().getNamedItem("name") != null) {
            tableOfData.setName(tableNode.getAttributes().getNamedItem("name").getNodeValue());
        }
        if (tableNode.getAttributes().getNamedItem("columnName") != null) {
            tableOfData.setColumnName(tableNode.getAttributes().getNamedItem("columnName").getNodeValue());
        }
        return tableOfData;
    }

    public Element buildDbItemToCheckElement(Document doc, DbItemToCheck dbItem, SchedulerFactoryBean schedulerFactoryBean) throws Exception {
        Element itemEl = doc.createElement("item");
        Element tableEl = doc.createElement("table");
        Element maxAgeOfDataEl = doc.createElement("maxAgeOfData");
        Element timeEventEl = doc.createElement("eventTime");
        Element stateEl = doc.createElement("state");
        Element descrEl = doc.createElement("description");
        Element datasourceEl = doc.createElement("datasource");
        Element lastCheckTime = doc.createElement("lastCheckTime");
        Element nextCheckTime = doc.createElement("nextCheckTime");

        lastCheckTime.setAttribute("value", dbItem.getLastCheckTime() == null ? "" : dbItem.getLastCheckTime().toString(XmlUtils.dateTimeFormat));
        nextCheckTime.setAttribute("value", xmlUtils.getNextCheckTime(dbItem, schedulerFactoryBean).toString(XmlUtils.dateTimeFormat));

        itemEl.setAttribute("id", dbItem.getId());
        itemEl.setAttribute("name", dbItem.getName());

        datasourceEl.setAttribute("id", dbItem.getDataSourceItem().getId());

        if (dbItem.getTable().getColumnName() != null) {
            tableEl.setAttribute("columnName", dbItem.getTable().getColumnName());
        }
        tableEl.setAttribute("name", dbItem.getTable().getName());

        if (dbItem.getMaxAgeOfData() != null) {
            maxAgeOfDataEl.setAttribute("age", dbItem.getMaxAgeOfData().getAge());
        }
        timeEventEl.setAttribute("cron", dbItem.getEventTime().getCron());

        List<Element> personElList = xmlUtils.buildPersonNodeList(doc, dbItem);
        if (dbItem.getCurrentStateName() != null) {
            stateEl.setAttribute("name", dbItem.getCurrentStateName().getName());
        }
        descrEl.setAttribute("descr", dbItem.getDescr());

        itemEl.appendChild(tableEl);
        itemEl.appendChild(maxAgeOfDataEl);
        itemEl.appendChild(timeEventEl);
        for (Element personEl : personElList) {
            itemEl.appendChild(personEl);
        }
        itemEl.appendChild(stateEl);
        itemEl.appendChild(descrEl);
        itemEl.appendChild(datasourceEl);
        itemEl.appendChild(lastCheckTime);
        itemEl.appendChild(nextCheckTime);

        return itemEl;
    }


    private String buildDescription(Node node) {
        if (node != null) {
            return node.getAttributes().getNamedItem("descr").getNodeValue();
        }
        return null;
    }


    private MaxAgeOfData buildmaxAgeOfData(Node node) {
        if (node != null && node.getAttributes().getNamedItem("age") != null) {
            String age = node.getAttributes().getNamedItem("age").getNodeValue();
            return new MaxAgeOfData(age);
        }
        return null;
    }
}
